///
/// ArmyBodger 3
/// (c)2010 richyp
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ArmyBodger.Core {
    /// <summary>
    /// An equipment option, is a unit specific instance of a peice of
    /// equipment, 
    /// </summary>
    public class EquipmentOption {
        /// <summary>
        /// Default Constructor
        /// </summary>
        public EquipmentOption() {
            this.Replacements = new EquipmentOptionCollection();
            this.CostOffset = 0;
        }
        /// <summary>
        /// Change the categoryname used
        /// </summary>
        public string OverridenCategoryName { get; set; }
        /// <summary>
        /// Reference to the actual equipment object
        /// </summary>
        public Equipment Equipment { get; set; }
        /// <summary>
        /// The cost of this equipment to this unit
        /// </summary>
        protected int cost = 0;
        public int Cost {
            get {
                return this.cost + CostOffset;
            }
            set {
                this.cost = value;
            }        
        }
        /// <summary>
        /// The maximum allowed number of this equipment
        /// </summary>
        public int CostOffset { get; set; }
        /// <summary>
        /// The maximum allowed number of this equipment
        /// </summary>
        public int Maximum { get; set; }
        /// <summary>
        /// Can this equipment be unequipped?
        /// </summary>
        public bool Fixed { get; set; }
        /// <summary>
        /// Is this item equipped?
        /// </summary>
        public bool Equipped { get; set; }
        /// <summary>
        /// Does the unit start with this item?
        /// </summary>
        public bool Default { get; set; }
        /// <summary>
        /// Does the weapon reroll to hit?
        /// </summary>
        public bool TwinLinked { get; set; }
        /// <summary>
        /// Name of a python function to call when item is equipped
        /// leave blank if no function is to be called
        /// </summary>
        public string OnEquipEvent { get; set; }
        /// <summary>
        /// Are there any replacement options available
        /// </summary>
        public bool HasReplacements {
            get {
                return this.Replacements.Count > 0;
            }
        }
        /// <summary>
        /// Is the option currently replaced?
        /// </summary>
        public bool IsReplaced
        {
            get
            {
                return this.Replacement != null;
            }
        }
        /// <summary>
        /// Is a replacement option applied
        /// </summary>
        public bool ReplacementApplied {
            get {
                return this.Replacement != null;
            }
        }
        /// <summary>
        /// The applied replacement
        /// </summary>
        public EquipmentOption Replacement { get; protected set; }
        /// <summary>
        /// Equip a replacement option
        /// </summary>
        /// <param name="name">The name of the replacement option to equip</param>
        public void EquipReplacement(string name) {
            this.Replacement = this.Replacements[name];
            this.Equipped = this.Replacement == null;
        }
        /// <summary>
        /// Reset the replacement option to null
        /// </summary>
        public void Reset() {
            if (this.Replacement != null)
            {
                this.Replacement.CostOffset = 0;
                this.Replacement = null;
            }
            this.Equipped = true;
        }
        /// <summary>
        /// Replacement options
        /// </summary>
        public EquipmentOptionCollection Replacements { get; set; }
        /// <summary>
        /// Create a copy of this EquipmentOption
        /// </summary>
        /// <returns>A new instance of this EquipmentOption</returns>
        public EquipmentOption Copy() {
            return EquipmentOption.Copy(this);
        }
        /// <summary>
        /// Static version of Copy that takes a source EquipmentOption instead
        /// </summary>
        /// <param name="source">The EquipmentOption object to copy</param>
        /// <returns>A new instance of the specified EquipmentOption</returns>
        public static EquipmentOption Copy(EquipmentOption source) {
            EquipmentOption option = new EquipmentOption();
            option.Equipment = source.Equipment;
            option.Cost = source.Cost;
            option.Maximum = source.Maximum;
            option.Fixed = source.Fixed;
            option.Equipped = source.Equipped;
            option.OnEquipEvent = source.OnEquipEvent;
            option.Default = source.Default;
            option.TwinLinked = source.TwinLinked;
            option.OverridenCategoryName = source.OverridenCategoryName;
            foreach (EquipmentOption replacement in source.Replacements) {
                option.Replacements.Add(replacement.Copy());
            }
            return option;
        }

        public String Description
        {
            get
            {
                string name = this.Equipment.Name;
                if (this.TwinLinked)
                {
                    name = "Twin-linked " + name;
                }
                return name;
            }
        }

        public override string ToString()
        {
            if (this.Replacement != null)
            {
                return this.Replacement.Description;
            }

            return this.Description;
        }
    }
}
